/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package dao;

import modelo.Sustrato;
import dao.generic.GenericDAO;
import java.util.ArrayList;
import java.util.Date;
import java.util.Iterator;
import java.util.List;
import javax.swing.JTextPane;
import modelo.GrupoLectura;
import modelo.Historial;
import modelo.Lectura;
import modelo.SustratoNave;
import org.hibernate.Criteria;
import org.hibernate.HibernateException;
import org.hibernate.Query;
import org.hibernate.criterion.ProjectionList;
import org.hibernate.criterion.Projections;
import org.hibernate.criterion.Restrictions;

/**
 *
 * @author Administrador
 */
public class SustratoDAO extends GenericDAO {

  public Sustrato getSustratoById(int idSustrato) {
    Sustrato s = null;
    try {
      iniciarOperacion();
      s = (Sustrato) sesion.get(Sustrato.class, idSustrato);
    } finally {
      sesion.close();
    }
    return s;
  }

  public List getListArray() {
    Iterator i;
    //lista que almacena los array, el numero de array es por numero de sustratos registrados
    List lista = new ArrayList();
    try {
      iniciarOperacion();
      i = sesion.createQuery("SELECT s.id ,count(elements(s.grupo)),s.nombre,s.referencia.optimo FROM Sustrato as s GROUP BY s").iterate();
      while (i.hasNext()) {
        Object[] obj = (Object[]) i.next();
        //array de tamño 5 almacena [id_sustrato,no_grupos,nombre_sustrato,valRef_optimo,no_lecturas,suma_lecturas,noApertura_valvulas]
        Object[] array = new Object[10];
        array[0] = obj[0];//id_sustrato
        array[1] = obj[1];//no. grupos
        array[2] = obj[2];//nombre sustrato
        array[3] = obj[3];//valor referencia
        array[4] = 0;//no de registros de lecturas
        array[5] = 0.0;//suma total de lecturas
        array[6] = 0;//no. apertura de valvulas
        array[7] = 0.0;//gasto acumulado
        array[8] = "";//grupos que se estan regando actualmente
        array[9] = "";//grupos que no se estan regando actualmente
        lista.add(array);
      }
    } finally {
      sesion.close();
    }
    return lista;
  }

  public void humedadPromedio(JTextPane panel, Date fecha) {
    Lectura l;
    Historial h;
    List lista;
    Iterator i;
    try {
      iniciarOperacion();
      Query query = sesion.createQuery("SELECT elements(h.lectura) FROM Historial as h where h.fecha= :fecha");
      query.setParameter("fecha", fecha);
      lista = query.list();
      for (Object obj : lista) {
        l = (Lectura) obj;

        for (GrupoLectura gl : l.getGrupoLectura()) {
          panel.setText(panel.getText() + "id lec: " + l.getId() + ", sustrato: " + l.getSustrato().getNombre() + ", estado vla: " + gl.getEstadoValvula() + "\n");
        }

      }

    } finally {
      sesion.close();
    }

  }

  public int numGrupos(String nombreSustrato) {
    int numGrupos = 0;

    try {
      iniciarOperacion();
      Query query = sesion.createQuery("SELECT count(elements(s.grupo)) FROM Sustrato as s WHERE s.nombre= :nombre");
      query.setParameter("nombre", nombreSustrato);
      numGrupos = Integer.parseInt(query.uniqueResult().toString());
      System.out.println(numGrupos);
    } catch (HibernateException e) {
      System.out.println("Error al calcular los grupos del sustrato");
    }
    return numGrupos;
  }

  public Iterator calcula(JTextPane panel, Date fecha) {
    Iterator i;
    try {
      iniciarOperacion();
      Query query = sesion.createQuery("SELECT elements(s.lectura) as lectura,count(elements(s.grupo)) FROM Sustrato as s where s.id in(SELECT l.sustrato.id FROM Lectura as l where l.historial.fecha= :fecha)");
      query.setParameter("fecha", fecha);
      i = query.iterate();
    } finally {
      sesion.close();
    }
    return i;
  }

  public List consultaNombresSustrato() {
    List lista;
    try {
      iniciarOperacion();
      Query query = sesion.createQuery("SELECT nombre FROM Sustrato");
      lista = query.list();
    } finally {
      sesion.close();
    }
    return lista;
  }

//  public Integer[] consultaSustratoByNave(String nombreNave) {
//    List list = null;
//    try {
//      iniciarOperacion();
//      Query query = sesion.createQuery("Select sn.primaryKey.sustratoFK.id FROM SustratoNave as sn where sn.primaryKey.naveFK.id in (select id from Nave where nombre = :nombreNave)");
//      query.setParameter("nombreNave", nombreNave);
//    } finally {
//      sesion.close();
//    }
//
//    return (Integer[]) list.toArray(new Integer[0]);
//  }

  public String[] consultaSustratoByNombreNave(String nombreNave) {
    List list = null;
    String consulta = "";
    Query query = null;
    try {
      iniciarOperacion();
      if (!nombreNave.equals("all")) {
        consulta = "SELECT sn.primaryKey.sustratoFK.nombre from SustratoNave as sn where sn.primaryKey.naveFK.nombre = :nombreNave";
        query = sesion.createQuery(consulta);
        query.setParameter("nombreNave", nombreNave);

      } else {
        consulta = "SELECT nombre from Sustrato";
        query = sesion.createQuery(consulta);
      }

      list = query.list();
      for (Object obj : list) {
        String s = (String) obj;
        System.out.println(s);
      }

    } finally {
      sesion.close();
    }
    return (String[]) list.toArray(new String[0]);
  }
  
  ///Consultas por criteria
  public List getListArrayCriteria(String []sustratos) {
    Iterator i;
    //lista que almacena los array, el numero de array es por numero de sustratos registrados
    List lista = new ArrayList();
    try {
      iniciarOperacion();
      Criteria criteria = sesion.createCriteria(Sustrato.class, "s");
      criteria.add(Restrictions.in("nombre", sustratos));
      ProjectionList listProy = Projections.projectionList();
      criteria.createCriteria("grupo");
      criteria.createCriteria("referencia", "r");
      listProy.add(Projections.groupProperty("s.id"));
      listProy.add(Projections.count("grupo"));
      listProy.add(Projections.property("s.nombre"));
      listProy.add(Projections.property("r.optimo"));
      

      i = criteria.setProjection(listProy).list().iterator();

      //i = sesion.createQuery("SELECT s.id ,count(elements(s.grupo)),s.nombre,s.referencia.optimo FROM Sustrato as s GROUP BY s").iterate();
      while (i.hasNext()) {
        Object[] obj = (Object[]) i.next();
        //array de tamño 10 almacena para almacenar la informacion que necesaria para  desplegar los datos de riego del dia
        Object[] array = new Object[10];
        array[0] = obj[0];//id_sustrato
        array[1] = obj[1];//no. grupos
        array[2] = obj[2];//nombre sustrato
        array[3] = obj[3];//valor referencia
        array[4] = 0;//no de registros de lecturas
        array[5] = 0.0;//suma total de lecturas
        array[6] = 0;//no. apertura de valvulas
        array[7] = 0.0;//gasto acumulado
        array[8] = "";//grupos que se estan regando actualmente
        array[9] = "";//grupos que no se estan regando actualmente
        lista.add(array);
      }
    } finally {
      sesion.close();
    }
    return lista;
  }
  //tratando de hace run join entre tablas de union 
  public void consultaSustratoByNave(String nave){
    Iterator i;
    try{
      iniciarOperacion();
      Criteria criteria= sesion.createCriteria(SustratoNave.class,"sn");
      criteria.createAlias("sn.primaryKey.naveFK", "nave");
      criteria.createAlias("sn.primaryKey.sustratoFK", "sustrato");
      ProjectionList proyeccion = Projections.projectionList();
      proyeccion.add(Projections.property("sustrato.nombre"));
      proyeccion.add(Projections.property("nave.nombre"));
//      criteria.setProjection(proyeccion);
      i = criteria.list().iterator();
      while(i.hasNext()){
        SustratoNave array = (SustratoNave) i.next();
        System.out.println(array.getPrimaryKey().getSustratoFK().getNombre()+" "+array.getPrimaryKey().getNaveFK().getNombre());
        
      }
              
    }
    finally{
      sesion.close();
    }
           
  }
    public float valorReferenciaOptimo(String nombreSustrato){
    float optimo;
    try{
      iniciarOperacion();
      Criteria criteria = sesion.createCriteria(Sustrato.class,"s")
              .createCriteria("s.referencia","r")
              .add(Restrictions.eq("s.nombre", nombreSustrato))
              .setProjection(Projections.property("r.optimo"));
      optimo= (Float)criteria.uniqueResult();
      
    }
    finally{
      sesion.close();
    }
    return optimo;
  }
  
  
  
}
